package com.lfy.ch02;


import org.junit.Test;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * OutputStream： 测试类； 测试往出写东西
 */
public class OutputStreamTest {


    /**
     * 解密程序: 跳着加密（只加密部分）
     */
    @Test
    public void testDecode() throws IOException {
        //1、定义输出流； 把内容写到哪里
        InputStream in = new FileInputStream("C:\\Users\\53409\\Desktop\\testSecurity.mp4");

        //2、定义输出流； 把内容写到哪里
        OutputStream out = new FileOutputStream("C:\\Users\\53409\\Desktop\\decode.mp4");

        //3、一次一个桶
        byte[] data = new byte[1024];

        int size = 0;
        while ((size = in.read(data)) != -1) {
            //3、写一个桶的数据;  处理最后一桶的问题(真实长度，因为有之前遗留、或者默认的0填充)

            //解密程序
            for (int i = 0; i < data.length; i++) {
                //解密： data[i] = data[i] ^ 5;
                data[i] ^= 5;
            }

            out.write(data, 0, size);
        }

        in.close();
        out.close();

    }

    /**
     * 字节混淆技术进行加密解密
     */
    @Test
    public void mp4EncodeDecode() throws IOException {

        //1、定义输入流； 要读取的内容
        InputStream in = new FileInputStream("C:\\Users\\53409\\Desktop\\java_all_in\\视频\\day14 - 泛型&IO\\视频\\12、Java基础 - IO - Files类操作.mp4");

        //2、定义输出流； 把内容写到哪里
        OutputStream out = new FileOutputStream("C:\\Users\\53409\\Desktop\\testSecurity.mp4");


        // 反向算法： ^ 异或， 相同为0，不同为1

        byte[] data = new byte[1024];
        int size = 0;
        while ((size = in.read(data)) != -1) {
            //3、写一个桶的数据;  处理最后一桶的问题(真实长度，因为有之前遗留、或者默认的0填充)


            //设计一个算法（与 5 进行 异或）： 加密和解密
            // 加密：
            // 1001 0110 ^
            // 0000 0101 =
            // 1001 0011

            // 解密：
            // 1001 0011 ^
            // 0000 0101 =
            // 1001 0110
            //准备存储加密后的字节数据
            byte[] encode = new byte[1024];

            for (int i = 0; i < data.length; i++) {
                int i1 = data[i] ^ 5;
                encode[i] = (byte) i1;
            }

            // 写入的是加密后的数据，不是原始的数据
            out.write(encode, 0, size);
        }



        in.close();
        out.close();
    }


    @Test
    public void testVideoQuick() throws IOException {
        //1、定义输入流； 要读取的内容
        InputStream in = new FileInputStream("C:\\Users\\53409\\Desktop\\java_all_in\\视频\\day14 - 泛型&IO\\视频\\12、Java基础 - IO - Files类操作.mp4");

        //2、定义输出流； 把内容写到哪里
        OutputStream out = new FileOutputStream("C:\\Users\\53409\\Desktop\\testQuick.avi");


        // 一桶就是1MB；
        byte[] bytes = new byte[1024 * 1024];

        // 一次读一个桶的数据; 最后一桶不一定装满 视频：
        // .mp4  .avi  .rmvb
        // .png .jpg
        int size = 0; //返回读了多少字节
        while ((size = in.read(bytes)) != -1) {
            //3、写一个桶的数据;  处理最后一桶的问题(真实长度，因为有之前遗留、或者默认的0填充)
            out.write(bytes, 0, size);
        }

        in.close();
        out.close();

    }


    /**
     * 复制一个视频； 太慢了
     *
     * @throws IOException
     */
    @Test
    public void testVideo() throws IOException {
        //1、定义输入流； 要读取的内容
        InputStream in = new FileInputStream("C:\\Users\\53409\\Desktop\\java_all_in\\视频\\day14 - 泛型&IO\\视频\\12、Java基础 - IO - Files类操作.mp4");


        //2、定义输出流； 把内容写到哪里
        OutputStream out = new FileOutputStream("C:\\Users\\53409\\Desktop\\test.mp4");


        //3、读一个字节，就写一个字节
//        int data = in.read();  // 77
//        while (data != -1){ //没结束； data就是这个字节
//            //4、写一个字节
//            out.write(data);
//            data = in.read(); //继续读下一个
//        }
        //综合写法
        int data = 0;
        while ((data = in.read()) != -1) {
            out.write(data);
        }


        in.close();
        out.close();


    }


    // 要求：用 字节流 把 kubla .txt 的内容 复制到 out2.txt
    @Test
    public void test() throws IOException {
        // 1、拿到输入流
        InputStream in = new FileInputStream("kubla .txt");

        //2、拿到输出流
        OutputStream out = new FileOutputStream("out2.txt");

        // byte 1个字节 8bit 最高位 符号位。 7bit
        // int 4个字节 32bit 最高位 符号位。 31bit
        int data = in.read(); //第一次读到一个
        while (data != -1) {
            //3、读一个字节，就写一个字节
            out.write(data);
            //4、继续读下一个
            data = in.read();
        }
        System.out.println("读完了，也写完了。。。");

        // 关闭流
        in.close();
        out.close();
    }


    /**
     * 测试输出流：  所有东西都没有办法直接写出去，除非转成01（字节【一个字节8个01】）
     *
     * @throws FileNotFoundException
     */
    @Test
    public void testOut1() throws IOException {
        OutputStream out = new FileOutputStream("out.txt");


        // 为什么写了 10 out中没有  77 == 一堆 010101
        out.write(77); // ASCII码表中 77 对应 M
        out.write(66); // B

        // 写入一个换行符
        out.write(10);
        out.flush(); // 刷新缓冲区，将缓冲区的数据写入到【目的地】

        String str = "雷丰阳666"; // 字符串转成二进制： 编码

        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        out.write(bytes);


        // 关闭流，1）、释放资源  2）、刷新缓冲区
        out.close();
    }
}
